//
//  TileMap.m
//  MapEdit
//
//  Created by Steven Canfield on 13/06/07.
//  Copyright 2007 __MyCompanyName__. All rights reserved.
//

#import "TileMap.h"

/* Gets and Sets the Tile_ID */
u_int8_t getTileID( u_int16_t tile ) {
	return (tile & 480) >> 5;
}

void setTileID( u_int16_t * tile, u_int8_t tile_id ) {
	u_int16_t storage = tile_id;
	// Clear Value
	*tile = *tile & ~480;
	// Store New Value
	*tile = *tile | ((storage << 5) & 480 );
}

/* Gets and Sets the Tile Variant */
u_int8_t getTileVariant( u_int16_t tile ) {
	return (tile & 7);
}
void setTileVariant( u_int16_t * tile, u_int8_t tile_variant ) {
	*tile = *tile & ~7;
	*tile = *tile | ( tile_variant & 7 );
}

/* Gets and Sets Whether the Tile has Decoration */
u_int8_t tileHasDecor( u_int16_t tile ) {
	return (tile & 8) >> 3;
}
void setHasDecor(  u_int16_t * tile, u_int8_t has_decor ) {
	*tile = *tile & ~8;
	*tile = *tile | (( has_decor << 3) & 8);
}

/* Gets and Sets the Even-Odd of the Tile */
u_int8_t tileIsEven( u_int16_t tile ) {
	return (tile & 16) >> 4;
}
void setTileIsEven( u_int16_t * tile, u_int8_t even_odd ) {
	*tile = *tile & ~16;
	*tile = *tile | (( even_odd << 4 ) & 16);
}

/* Gets and Sets the Border ID */
u_int8_t getBorderID( u_int16_t tile ) {
	return (tile & 32256 ) >> 9;
}
void setBorderID( u_int16_t * tile, u_int8_t border_id ) {
	*tile = *tile & ~32256;
	*tile = *tile | ((border_id << 9 ) & 32256);
}


@implementation TileMap
- (id)initWithData:(NSData *)data size:(NSSize)size
{
	self = [super init];
	
	if( self ) {
		_size = size;
		_tiles = malloc( sizeof( u_int16_t ) * _size.width * _size.height );
		[data getBytes:_tiles];
		
		int x;
		int y;
		for( x = 0; x < (int)_size.width; x++ ) {
			for( y = 0; y < (int)_size.height; y++ ) {
				_tiles[ y *  (int)_size.width + x ] = NSSwapLittleShortToHost(_tiles[ y *  (int)_size.width + x ]);
			}
		}
		
	}
	
	return self;
}

- (NSData * )serializedMap {
	NSMutableData * data = [[NSMutableData alloc] init];
	[data appendSectionNamed:"MTXM" withBytes:_tiles length:((int)_size.width * (int)_size.height * sizeof( u_int16_t ))];
	return data;
}

- (int)width {
	return (int)_size.width;
}

- (int)height {
	return (int)_size.height;
}

- (void)dealloc {
	free( _tiles );
	[super dealloc];
}

- (u_int16_t)tileAtX:(int)x Y:(int)y {
	return _tiles[ ((int)_size.height - y - 1) * (int)_size.width + x];
}
- (int)tileIdentiferAtX:(int)x Y:(int)y {
	return getTileID( _tiles[ ((int)_size.height - y - 1) * (int)_size.width + x] );
}

- (int)tileVariantX:(int)x Y:(int)y {
	return getTileVariant( _tiles[ ((int)_size.height - y- 1) * (int)_size.width + x] );
}

- (BOOL)tileIsBorderAtX:(int)x Y:(int)y {
	return (getBorderID( _tiles[((int)_size.height - y- 1) * (int)_size.width + x] ) != 0 );
}

@end
